// 云函数入口文件
const cloud = require('wx-server-sdk')
const dayjs = require('dayjs')
dayjs.extend(require('dayjs/plugin/isoWeek'))

cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV })

const db = cloud.database()
const _ = db.command

// 云函数入口函数
exports.main = async event => {
  const { returnCode, resultCode, outTradeNo } = event
  if (!outTradeNo) {
    throw new Error('no outTradeNo')
  }

  const {
    data: [oData],
  } = await db.collection('order').where({ _id: outTradeNo, status: 0 }).get()
  if (!oData) {
    throw new Error('order not found')
  }
  const { _openid, promotion, casts } = oData

  const success = returnCode && resultCode
  await db
    .collection('order')
    .doc(outTradeNo)
    .update({
      data: {
        result: event,
        status: success ? 1 : undefined,
      },
    })
  if (!success) {
    throw new Error('trade failed')
  }

  const {
    data: [store],
  } = await db
    .collection('store')
    .field({ _openid: false, owner: false, account: false, audit: false })
    .where({ _openid })
    .get()
  promotion.store = store

  for (let { screen, weeks } of casts) {
    for (let week of weeks) {
      await Promise.all([
        (async () => {
          const { total } = await db
            .collection('screen-cast')
            .where({ screen: { _id: screen._id }, week })
            .count()
          if (total) {
            await db
              .collection('screen-cast')
              .where({ screen: { _id: screen._id }, week })
              .update({ data: { promotions: _.push(promotion) } })
          } else {
            await db.collection('screen-cast').add({
              data: { screen, week, promotions: [promotion] },
            })
          }
        })(),
        (async () => {
          const { total } = await db
            .collection('promotion-cast')
            .where({ promotion: { _id: promotion._id }, week })
            .count()
          if (total) {
            await db
              .collection('promotion-cast')
              .where({ promotion: { _id: promotion._id }, week })
              .update({ data: { screens: _.push(screen) } })
          } else {
            const currQuota = {}
            const start = dayjs(week).startOf('isoWeek')
            for (let i = 0; i <= 6; i++) {
              currQuota[start.add(i, 'day').format('YYYY-MM-DD')] =
                promotion.quota
            }
            await db.collection('promotion-cast').add({
              data: { promotion, week, screens: [screen], currQuota },
            })
          }
        })(),
      ])
    }
  }

  return { errcode: 0 }
}
